package srv

import (
	"go-init/dao"
	"strings"

	"github.com/go-redis/redis/v7"

	jsoniter "github.com/json-iterator/go"
)

func UserNavsAll(navs, auths string, level, parentid int) (usernavs []dao.UserNav, err error) {
	qs := dao.NewQs()
	qs.Add("a.level=?", level)
	qs.Add("a.parent_id=?", parentid)
	if navs != "" && level != 1 {
		qs.Add("a.id in("+navs+")", false)
	}
	usernavs, err = dao.UserNavs(qs, dao.Other{Offset: -1, OrderBy: "a.sort desc"})
	if len(usernavs) == 0 {
		return
	}
	if err != nil {
		return
	}
	level++
	qsc := dao.NewQs()
	if auths != "" {
		qsc.Add("a.id in("+auths+")", false)
	}
	for i := range usernavs {
		qsc.Add("a.user_nav_id=?", usernavs[i].Id)
		usernavs[i].UserNavAuth, err = dao.UserNavAuths(qsc, dao.Other{Offset: -1})
		if err != nil {
			return
		}
		usernavs[i].UserNav, err = UserNavsAll(navs, auths, level, usernavs[i].Id)
		if err != nil {
			return
		}
	}
	return
}

func UserNav(uid int) (usernavs []dao.UserNav, auth []dao.UserNavAuth, err error) {
	qs := dao.NewQs()
	qs.Add("a.id=?", uid)
	user, err := dao.Usero(qs)
	if err != nil {
		return
	}
	usernavs, err = UserNavsAll(user.Navs, user.Auths, 1, 0)
	if err != nil {
		return
	}
	if usernavs != nil {
		usernavs[0].Redirect = "/" + usernavs[0].UserNav[0].Key + "/" + strings.Split(usernavs[0].UserNav[0].UserNav[0].Key, "/")[0]
	}
	auth, err = dao.UserNavAuths(dao.NewQs(), dao.Other{Offset: -1, GroupBy: "a.user_nav_id"})
	if err != nil {
		return
	}
	if user.Auths != "" {
		for i := range auth {
			var childs []string
			qs2 := dao.NewQs()
			qs2.Add("a.user_nav_id=?", auth[i].UserNavId)
			qs2.Add("a.id in ("+user.Auths+")", false)
			child, err2 := dao.UserNavAuths(qs2, dao.Other{Offset: -1})
			if err2 != nil {
				err = err2
				return
			}
			for j := range child {
				childs = append(childs, child[j].Action)
			}
			auth[i].ActionList = childs
		}
	}
	return
}

func GetNavCache() (navs []dao.UserNav, err error) {
	res, err := dao.RedisClient.Get("nav").Result()
	if err != nil {
		if err == redis.Nil {
			navs, err = FlushNav()
			return
		}
		return
	}
	err = jsoniter.Unmarshal([]byte(res), &navs)
	if err != nil {
		return
	}
	return
}

func FlushNav() (navs []dao.UserNav, err error) {
	navs, err = UserNavsAll("", "", 1, 0)
	if err != nil {
		return
	}
	navjson, err := jsoniter.Marshal(navs)
	if err != nil {
		return
	}
	err = dao.RedisClient.Set("nav", navjson, 5e11).Err()
	return
}
